package com.pro.framework.javatodb.model;

import com.pro.framework.api.enums.EnumSortDirection;
import com.pro.framework.javatodb.constant.JTDConstInner;
import com.pro.framework.javatodb.util.JTDUtil;
import lombok.Data;
import lombok.ToString;
import lombok.experimental.SuperBuilder;

import java.io.Serializable;
import java.text.MessageFormat;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author administrator
 * @date 2022-01-20
 */
@Data
@SuperBuilder
@ToString
public class JTDSequenceInfo implements ISqlSegmentInfo, Serializable {

    /**
     * 索引名称
     */
    private String name;

    /**
     * 索引类型
     */
    private JTDConstInner.EnumSequenceType type;

    /**
     * 索引名称字段 有序
     */
    private List<IndexField> fields;


    /**
     * sql配置项 转 sql
     *
     * @param tableName
     * @return sql 例如: UNIQUE KEY `uk_variable_valName` (`variable`,`val_name`) USING BTREE
     */
    @Override
    public String toSql(String tableName) {
        return Stream.of(
                type.getValue(),
                MessageFormat.format("`{0}`", name),
                MessageFormat.format("({0})",
                        fields.stream()
                                .map(field -> {
                                    String expr = field.getExpression();
                                    // 对纯字段名加反引号；表达式原样输出
                                    if (!expr.contains("(") && !expr.contains(" ") && !expr.contains("`")) {
                                        expr = "`" + expr + "`";
                                    }
                                    String order = field.getOrder() == null
                                            || field.getOrder() == EnumSortDirection.ASC
                                            ? ""
                                            : " DESC";
                                    return expr + order;
                                })
                                .collect(Collectors.joining(","))
                )
        ).filter(JTDUtil::isNotBlank).collect(Collectors.joining(" "));
    }

    /**
     * sql 转 sql配置项
     *
     * @param sequenceConfigSql 例如:  UNIQUE KEY `uk_variable_valName` (`variable`,`val_name`) USING BTREE
     */
    public static JTDSequenceInfo init(String sequenceConfigSql) {
        if (JTDUtil.isBlank(sequenceConfigSql)) {
            return null;
        }

        JTDConstInner.EnumSequenceType type = JTDConstInner.EnumSequenceType.KEY;
        String subLine = sequenceConfigSql;

        if (subLine.trim().startsWith("UNIQUE")) {
            subLine = subLine.trim();
            subLine = subLine.substring(6);
            type = JTDConstInner.EnumSequenceType.UNIQUE_KEY;
        }
        if (subLine.trim().startsWith("KEY")) {
            subLine = subLine.trim();
            subLine = subLine.substring(3);
        }

        String name = subLine.trim().split(" ")[0].replaceAll("`", "");

        List<IndexField> fields = extractFieldsSafely(subLine);

        boolean hasExpressionField = fields.stream()
                .anyMatch(f -> f.getExpression().contains("(") && f.getExpression().contains(")"));
        if (hasExpressionField) {
            // 如果你只想标记表达式唯一索引，可以按你原来的逻辑再处理
            type = JTDConstInner.EnumSequenceType.EXPRESSION_UNIQUE_INDEX;
        }

        return JTDSequenceInfo.builder()
                .name(name)
                .type(type)
                .fields(fields)
                .build();
    }

    /**
     * 从一整行 KEY/UNIQUE KEY 定义中提取字段 + 排序信息
     * 示例：
     * KEY `idx_xxx` (`a` DESC, `b`, (create_time + 1) DESC)
     */
    public static List<IndexField> extractFieldsSafely(String line) {
        List<IndexField> result = new ArrayList<>();

        int start = line.indexOf('(');
        int end = line.lastIndexOf(')');
        if (start == -1 || end == -1 || end <= start) {
            return result;
        }

        String fieldExpr = line.substring(start + 1, end).trim();
        StringBuilder current = new StringBuilder();
        int parenDepth = 0;
        boolean insideBacktick = false;

        for (int i = 0; i < fieldExpr.length(); i++) {
            char c = fieldExpr.charAt(i);

            if (c == '`') {
                insideBacktick = !insideBacktick;
            } else if (!insideBacktick) {
                if (c == '(') parenDepth++;
                if (c == ')') parenDepth--;
            }

            if (c == ',' && parenDepth == 0 && !insideBacktick) {
                // 一个字段结束
                String part = current.toString().trim();
                if (!part.isEmpty()) {
                    result.add(parseFieldPart(part));
                }
                current.setLength(0);
            } else {
                current.append(c);
            }
        }

        if (current.length() > 0) {
            String part = current.toString().trim();
            if (!part.isEmpty()) {
                result.add(parseFieldPart(part));
            }
        }

        return result;
    }

    /**
     * " `a` DESC " / " `b` " / " (create_time + 1) DESC "
     * 解析出 expression + order
     */
    private static IndexField parseFieldPart(String part) {
        // 按空白拆分，但要考虑表达式里可能有空格，所以只把最后一个 token 识别为 ASC/DESC（如果是的话）
        // 示例：
        //   `a` DESC -> ["`a`", "DESC"]
        //   (create_time + 1) DESC -> ["(create_time", "+", "1)", "DESC"]
        //   `b` -> ["`b`"]
        String[] tokens = part.trim().split("\\s+");
        EnumSortDirection order = EnumSortDirection.ASC;
        String expr;

        if (tokens.length >= 2) {
            String last = tokens[tokens.length - 1].toUpperCase(Locale.ROOT);
            if ("ASC".equals(last) || "DESC".equals(last)) {
                order = "DESC".equals(last)
                        ? EnumSortDirection.DESC
                        : EnumSortDirection.ASC;
                // 去掉最后一个 token，剩下的是表达式
                expr = String.join(" ",
                        Arrays.stream(tokens, 0, tokens.length - 1).toArray(String[]::new));
            } else {
                expr = part.trim();
            }
        } else {
            expr = part.trim();
        }

        expr = stripOuterBackticks(expr);

        return IndexField.builder()
                .expression(expr)
                .order(order)
                .build();
    }

    private static String stripOuterBackticks(String s) {
        String trimmed = s.trim();
        if (trimmed.startsWith("`") && trimmed.endsWith("`")) {
            return trimmed.substring(1, trimmed.length() - 1);
        }
        // 对于表达式，去掉多余空格即可，不要全局 replaceAll(" ", "")
        return trimmed.replaceAll(",\\s+", ",");
    }

    public static void main(String[] args) {
        String sql = "UNIQUE KEY `uk_shopId_outId_deleted` (`shop_id`,`out_id`,(if((`deleted` = 0), 1, NULL)))";
//        String sql = "UNIQUE KEY `idx_user` (`user_id` DESC, `name`, (create_time + 1) DESC) USING BTREE";

        JTDSequenceInfo info = JTDSequenceInfo.init(sql);
        System.out.println(info);

        String backSql = info.toSql("t_user");
        System.out.println(backSql);

        // 预期输出类似：
        // UNIQUE KEY `idx_user` (`user_id` DESC,`name`,(create_time + 1) DESC)
    }

}
